#pragma once
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>

/*
    对spdlog二次封装：
    1、提供日志打印的当前文件和当前行号（只能通过宏和编译器共同完成）
    2、针对调试和发布两种不同模式，分别将日志输出到标准输出和文件中
    3、方便再命令行中进行模式控制
*/
namespace ns_spdlogger
{
    std::shared_ptr<spdlog::logger> sync_logger;

    // mode：日志模式 -- true:发布模式，false:调试模式
    // release_level 发布模式下，日志记录等级
    void init_logger(bool mode, int release_level = 0, const std::string &file = "log.txt")
    {
        if (mode == true)
        {
            // 创建文件输出日志器
            sync_logger = spdlog::basic_logger_mt("basefile-logger", file, false);

            // 设置日志记录等级
            sync_logger->set_level((spdlog::level::level_enum)release_level);

            // 设置刷次等级策略
            sync_logger->flush_on((spdlog::level::level_enum)release_level);
        }
        else
        {
            // 创建标准输出日志器
            sync_logger = spdlog::stdout_color_mt("stdout-logger");

            // 设置日志记录等级
            sync_logger->set_level(spdlog::level::level_enum::trace);

            // 设置刷次等级策略
            sync_logger->flush_on(spdlog::level::level_enum::critical);
        }
        // 设置日志格式
        sync_logger->set_pattern("[%n][%H:%m:%S][%t][%-5l]%v"); // n:日志记录器名称，t:线程名称，l:日志等级名称，v:日志内容
    }
}

#define LOG_TRACE(format, ...)                                                                                \
    do                                                                                                        \
    {                                                                                                         \
        ns_spdlogger::sync_logger->trace(std::string("[{}:{}]") + format, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define LOG_DEBUG(format, ...)                                                                                \
    do                                                                                                        \
    {                                                                                                         \
        ns_spdlogger::sync_logger->debug(std::string("[{}:{}]") + format, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define LOG_INFO(format, ...)                                                                                \
    do                                                                                                       \
    {                                                                                                        \
        ns_spdlogger::sync_logger->info(std::string("[{}:{}]") + format, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define LOG_WARN(format, ...)                                                                                \
    do                                                                                                       \
    {                                                                                                        \
        ns_spdlogger::sync_logger->warn(std::string("[{}:{}]") + format, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define LOG_ERROR(format, ...)                                                                                \
    do                                                                                                        \
    {                                                                                                         \
        ns_spdlogger::sync_logger->error(std::string("[{}:{}]") + format, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)

#define LOG_FATAL(format, ...)                                                                                   \
    do                                                                                                           \
    {                                                                                                            \
        ns_spdlogger::sync_logger->critical(std::string("[{}:{}]") + format, __FILE__, __LINE__, ##__VA_ARGS__); \
    } while (0)
